package com.siyoumi.mybatispuls;

import com.siyoumi.component.http.XHttpContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.sql.PreparedStatement;

/**
 * SQL拦截器
 */
@Slf4j
@Component
@Intercepts({
        @Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})
})
public class SqlLogInterceptor
        implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        PreparedStatement statement = (PreparedStatement) invocation.getArgs()[0];
        PreparedStatement sqlStatement = null;

        //等待方法结果出来
        Object result = invocation.proceed();

        if (Proxy.isProxyClass(statement.getClass())) {
            InvocationHandler handler = Proxy.getInvocationHandler(statement);
            if (handler.getClass().getName().endsWith(".PreparedStatementLogger")) {
                Field field = handler.getClass().getDeclaredField("statement");
                field.setAccessible(true);
                sqlStatement = (PreparedStatement) field.get(handler);
            }
        }

        if (sqlStatement != null) {
            String sql = sqlStatement.toString().substring(sqlStatement.toString().indexOf(":") + 1);
            sql = sql.replace("\n", "");
            XHttpContext.set("sql", sql);
            log.debug("SQL:{}", sql);
        }

        return result;
    }
}
